<?php
namespace app\controller;

use app\BaseController;
use think\facade\Request;
use think\facade\Db;
use think\Exception;
use think\facade\Filesystem;
use think\facade\Log;
use think\Event;
use app\event\AssetHistoriesEvent;

class AssetReturnsBill extends BaseController
{

    //查询所有退库单及其明细
    public function getAllAssetReturnsBill()
    {
        $userRoot = $this->request->auth['data']->user->user_root;
        $userId = $this->request->auth['data']->user->user_id;


        // 根据用户ID获取公司ID
        $companyId = Db::name('user')->where('user_id', $userId)->value('user_company_id');

        $current_page = Request::param('current_page');
        $page_size = Request::param('page_size');


        // 获取搜索表单参数
        $seachform = Request::param('seachform', [], 'trim'); // 使用trim过滤空白字符，并设置默认值为空数组

        //批量检查参数是否存在
        if (is_array($seachform)) {
            $begindate = $seachform['startDate'] ?? null;//开始日期购买日期
            $enddate = $seachform['endDate'] ?? null;//结束日期购买日期
            $billnumber = $seachform['BillNumber'] ?? null;//退库单号
            $state = $seachform['state'] ?? null;//退库单状态
            $branchId=$seachform['AssetReturnsBill_branch_id'] ?? null;

        }

        // 构建查询条件
        $where = [];

        if ($begindate && $enddate) {
            // 设置开始日期的时分秒为00:00:00
            $startOfDay = date('Y-m-d 00:00:00', strtotime($begindate));
            // 设置结束日期的时分秒为23:59:59（或者你也可以选择结束日期的次日00:00:00来简化比较）
            $endOfDay = date('Y-m-d 23:59:59', strtotime($enddate));

            // 使用范围查询
            $where[] = ['AssetReturnsBill_creationtime', '>=', $startOfDay];
            $where[] = ['AssetReturnsBill_creationtime', '<=', $endOfDay];
        }
        if ($billnumber) {
            $where[] = ['AssetReturnsBill_BillNumber', 'like', '%' . $billnumber . '%'];

        }
        if ($companyId) {
            $where['AssetReturnsBill_company_id'] = $companyId;
        }
        if ($state) {
            $where['AssetReturnsBill_state'] = $state;
        }

        if ($branchId) {
            $where['AssetReturnsBill_branch_id'] = $branchId;
        }

        // 查询主表数据,按照PurchaseBill_creationtime时间字段排序
        $mainList = Db::table('vw_AssetReturnsBill')
            ->where($where)
            ->where('AssetReturnsBill_deleted', 0)
            ->order('AssetReturnsBill_creationtime', 'desc')//按时间降序排名
            ->page($current_page, $page_size)
            ->select()->toarray();

        foreach ($mainList as &$item) {
            // 查询对应的明细表数据
            $detailList = Db::table('vw_AssetReturnsBill_assets')
                ->where('AssetReturnsBill_id', $item['AssetReturnsBill_id'])
                ->select();

            // 将明细表数据附加到主表数据上
            $item['detail'] = $detailList;
        }
        unset($item); // 取消引用，避免后续对$item的修改影响到$mainList

        // 获取总记录数
        $totalCount = Db::table('vw_AssetReturnsBill')
            ->where($where)
            ->where('AssetReturnsBill_deleted', 0)
            ->order('AssetReturnsBill_creationtime', 'desc')//按时间降序排名
            ->count();

        // 返回JSON数据
        return json([
            'code' => 200, // 自定义状态码，0表示成功
            'msg' => '查询成功', // 自定义消息
            'data' => [
                'data' => $mainList, // 主表数组包含明细表数组
                'total' => $totalCount, // 总数量

            ]

        ]);



    }

    //添加退库单
    public function add_AssetReturnsBill()
    {
        $userRoot = $this->request->auth['data']->user->user_root;
        $userId = $this->request->auth['data']->user->user_id;


        // 根据用户ID获取公司ID
        $companyId = Db::name('user')->where('user_id', $userId)->value('user_company_id');


        try {
            // 开启事务
            Db::startTrans();
            //生成退库单号
            $billnumber = generateOrderNumber($companyId,'TK','AssetReturnsBill');
            //获取退库单的传参退库单信息和明细表信息
            $AssetReturnsBill = Request::param('AssetReturnsBill');
            $assets = filterEmptyValues(Request::param('assets'));
            //找查资产是否被其他退库单占用
//            foreach ($assets as $asset){
//                $findId=Db::table('AssetReturnsBill_assets')->where('assets_id',$asset['assets_id'])->value('AssetReturnsBill_id');
//                if ($findId)
//                {
//                    $findAsset=Db::table('AssetReturnsBill')->where('AssetReturnsBill_id',$findId)->where('AssetReturnsBill_state','未审核')->value('AssetReturnsBill_BillNumber');
//                    if($findAsset)
//                    {
//                        return json([
//                            'code' => 201,
//                            'msg' => '资产:'.$asset['assets_name'].' '.'编码:'.$asset['assets_code'].'已经被未审核退库单:'.$findAsset.'占用，请先处理此单据'
//                        ]);
//                    }
//
//                }
//
//            }
            //检查资产是否被其他未审核单据占用
            $resultJson=checkAssetOccupy($assets,'AssetReturnsBill','退库单');
            if($resultJson){
                return $resultJson;
            }


            $AssetReturnsBill['AssetReturnsBill_company_id'] = $companyId;
            $AssetReturnsBill['AssetReturnsBill_BillNumber'] = $billnumber;
            $AssetReturnsBill['AssetReturnsBill_state'] = '未审核';
            $AssetReturnsBill['AssetReturnsBill_quantity'] = count(Request::param('assets'));
            $AssetReturnsBill['AssetReturnsBill_user_id'] = $userId;

            $AssetReturnsBillId = Db::table('AssetReturnsBill')->insertGetId($AssetReturnsBill);

            if (!$AssetReturnsBillId) {
                throw new \Exception('添加领货单主记录失败');
            }

            // 遍历货品明细并添加记录
            foreach ($assets as $detail) {
                // 生成条码（这里假设有一个generateBarcode函数）
                //$barcode = generateBarcode($companyId);

                //$DetailBill = $detail;
                $DetailBill['AssetReturnsBill_id'] = $AssetReturnsBillId;
                //$DetailBill['AssetReturnsBill_company_id'] = $companyId;
                $DetailBill['assets_id'] = $detail['assets_id'];
                $DetailBill['before_department_id'] = $detail['assets_department_id'];
                $DetailBill['after_department_id'] = $AssetReturnsBill['AssetReturnsBill_department_id'];
                $DetailBill['before_location_id'] = $detail['assets_location_id'];
                $DetailBill['after_location_id'] = $AssetReturnsBill['AssetReturnsBill_location_id'];
                $DetailBill['before_branch_id']=$detail['assets_branch_id'];
                $DetailBill['after_branch_id']=$AssetReturnsBill['AssetReturnsBill_branch_id'];
                $DetailBill['before_customer_id']=$detail['assets_customer_id'];
                $DetailBill['before_status']=$detail['assets_status'];

                $result = Db::table('AssetReturnsBill_assets')->insert($DetailBill);
                if (!$result) {
                    throw new \Exception('添加退库单明细记录失败');
                }
            }

            // 提交事务
            Db::commit();

            // 添加成功，返回响应
            return json(['code' => '200', 'msg' => '退库单添加成功']);






        } catch (\Exception $e) {
            // 发生异常，回滚事务
            Db::rollback();

            // 返回错误信息
            return json(['code' => '402', 'msg' => $e->getMessage()]);
        }

    }

    //修改退库单主表
    public function update_AssetReturnsBill()
    {

        $userRoot = $this->request->auth['data']->user->user_root;
        $userId = $this->request->auth['data']->user->user_id;


        // 根据用户ID获取公司ID
        $companyId = Db::name('user')->where('user_id', $userId)->value('user_company_id');

        try {
            Db::startTrans();
            $AssetReturnsBill_id = Request::param('AssetReturnsBill_id');
            $AssetReturnsBill = Request::param('data');
            //验证退库单是否合法,是否未审核状态
            $result=Db::table('AssetReturnsBill')
                ->where('AssetReturnsBill_id',$AssetReturnsBill_id)
                ->where('AssetReturnsBill_state','未审核')
                ->find();
            //返回Json数据
            if(empty($result)){
                return json([
                    'code' => 201,
                    'msg' => '该退库单状态不是未审核状态，不能修改'
                ]);
            }


            if(empty($AssetReturnsBill)){
                throw new \Exception('修改数据不能为空');
            }else{
                $updateResult = Db::table('AssetReturnsBill')
                    ->where('AssetReturnsBill_id', $AssetReturnsBill_id)
                    ->update($AssetReturnsBill);

                //修改与之关联的AssetReturnsBill_assets表,只需要修改退库后的字段
                $result=Db::table('AssetReturnsBill_assets')
                    ->where('AssetReturnsBill_id',$AssetReturnsBill_id)
                    ->update([
                        'after_department_id'=>$AssetReturnsBill['AssetReturnsBill_department_id'],
                        'after_location_id'=>$AssetReturnsBill['AssetReturnsBill_location_id'],
                        'after_branch_id'=>$AssetReturnsBill['AssetReturnsBill_branch_id'],
                    ]);


                if (!$updateResult) {
                    throw new \Exception('更新退库单信息失败');
                }else{
                    Db::commit();
                    //返回更新成功信息
                    return json(['code' => 200,'msg' => '更新成功']);
                }
            }





        }catch (\Exception $e) {
            Db::rollback();
            return json(['code' => 500, 'msg' => $e->getMessage()]);
        }

    }

    //审核退库单
    public function check_AssetReturnsBill()
    {

        $userRoot = $this->request->auth['data']->user->user_root;
        $userId = $this->request->auth['data']->user->user_id;


        // 根据用户ID获取公司ID
        $companyId = Db::name('user')->where('user_id', $userId)->value('user_company_id');

        $AssetReturnsBill_id =Request::param('AssetReturnsBill_id');

        //验证退库单是否合法,是否未审核状态
        $result=Db::table('AssetReturnsBill')
            ->where('AssetReturnsBill_id',$AssetReturnsBill_id)
            ->where('AssetReturnsBill_state','未审核')
            ->find();
        //返回Json数据
        if(empty($result)){
            return json([
                'code' => 201,
                'msg' => '该退库单状态不是未审核状态，不能审核'
            ]);
        }

        //审核前先查询资产的信息是否有改变，如果有则提示用户重新提单
        $AssetReturnsBill=Db::table('AssetReturnsBill_assets')->where('AssetReturnsBill_id',$AssetReturnsBill_id)->select();
        foreach ($AssetReturnsBill as $checkAssetItem){
            $Asset=Db::table('assets')->where('assets_id',$checkAssetItem['assets_id'])->find();
            if($Asset==null){
                return json(['code' => 201, 'msg' => '此单据有资产已被删除，请作废单据后重新提单']);
            }
            //将资产的信息与退库单的明细信息进行对比
            if($Asset['assets_status']!=$checkAssetItem['before_status']|| $Asset['assets_department_id']!=$checkAssetItem['before_department_id']||$Asset['assets_location_id']!=$checkAssetItem['before_location_id'] || $Asset['assets_InputStatus']!='已审核' || $Asset['assets_branch_id']!=$checkAssetItem['before_branch_id'] || $Asset['assets_customer_id']!=$checkAssetItem['before_customer_id']){
                return json(['code' => 201, 'msg' => '资产:'.$Asset['assets_name'].' '.'编码:'.$Asset['assets_code'].'资产信息有改变，请作废单据后重新提单']);
            }
        }

        //审核退库单
        try {
            Db::startTrans();
            //直接审核退库单，更改退库单状态未已审核
            $updateResult = Db::table('AssetReturnsBill')
                ->where('AssetReturnsBill_id', $AssetReturnsBill_id)
                ->update(['AssetReturnsBill_state' => '已审核']);



            // 首先，获取AssetReturnsBill_assets表中需要的所有信息
            $AssetReturnsBillAssets = Db::table('AssetReturnsBill_assets')
                ->where('AssetReturnsBill_id', $AssetReturnsBill_id)
                ->select();

            // 准备用于更新的数据
            $updateData = [];

            //构造修改资产的数据集
            foreach ($AssetReturnsBillAssets as $asset) {
                $updateData[] = [
                    'assets_id' => $asset['assets_id'],
                    'assets_status' => '闲置',
                    'assets_department_id' => $asset['after_department_id'], // 假设这些字段存在
                    'assets_location_id' => $asset['after_location_id'],
                    'assets_branch_id'=>$asset['after_branch_id']
                ];
            }

            //修改资产状态
            foreach ($updateData as $data) {
                Db::table('assets')
                    ->where('assets_id', $data['assets_id'])
                    ->update([
                        'assets_status' => $data['assets_status'],
                        'assets_department_id' => $data['assets_department_id'],
                        'assets_location_id' => $data['assets_location_id'],
                        'assets_customer_id'=>null,
                        'assets_branch_id'=>$data['assets_branch_id']
                    ]);
            }

            //使用事件触发器记录历史记录
            event(new AssetHistoriesEvent($AssetReturnsBill_id, $updateData, $userId, $companyId,'退库'));


            //直接返回json结果
            if (!$updateResult) {
                Db::rollback();
                throw new \Exception('审核退库单失败');
            }else{
                Db::commit();
                //返回审核成功信息
                return json(['code' => 200,'msg' => '审核成功']);
            }

        }
        catch (\Exception $e) {
            Db::rollback();
            return json([
                'code' => 500,
                'msg' => $e->getMessage()
            ]);
        }
        
    }
    
    //作废退库单
    public function  invalid_AssetReturnsBill()
    {

        $userRoot = $this->request->auth['data']->user->user_root;
        $userId = $this->request->auth['data']->user->user_id;


        // 根据用户ID获取公司ID
        $companyId = Db::name('user')->where('user_id', $userId)->value('user_company_id');
        try {
            Db::startTrans();
            $AssetReturnsBill_id =Request::param('AssetReturnsBill_id');

            //验证退库单是否合法,是否未审核状态
            $result=Db::table('AssetReturnsBill')
                ->where('AssetReturnsBill_id',$AssetReturnsBill_id)
                ->where('AssetReturnsBill_state','未审核')
                ->find();
            //返回Json数据
            if(empty($result)){
                return json([
                    'code' => 201,
                    'msg' => '该退库单状态不是未审核状态，不能作废'
                ]);
            }
            //作废退库单
            $updateResult = Db::table('AssetReturnsBill')
                ->where('AssetReturnsBill_id', $AssetReturnsBill_id)
                ->update(['AssetReturnsBill_state' => '已作废']);
            //直接返回json结果
            if (!$updateResult) {
                Db::rollback();
                throw new \Exception('作废退库单失败');
            }else{
                Db::commit();
                //返回作废成功信息
                return json(['code' => 200,'msg' => '作废成功']);
            }

        }
        catch (\Exception $e) {
            Db::rollback();
            return json([
                'code' => 500,
                'msg' => $e->getMessage()
            ]);
        }
        
        
        
    }
    
    //删除退库单
    public function  delete_AssetReturnsBill()
    {

        $userRoot = $this->request->auth['data']->user->user_root;
        $userId = $this->request->auth['data']->user->user_id;


        // 根据用户ID获取公司ID
        $companyId = Db::name('user')->where('user_id', $userId)->value('user_company_id');

        try {
            Db::startTrans();
            $AssetReturnsBill_id =Request::param('AssetReturnsBill_id');
            //验证退库单是否合法,是否未审核状态
            $result=Db::table('AssetReturnsBill')
                ->where('AssetReturnsBill_id',$AssetReturnsBill_id)
                ->where('AssetReturnsBill_state','已作废')
                ->find();
            //返回Json数据
            if(empty($result)){
                return json([
                    'code' => 201,
                    'msg' => '该退库单状态不是作废状态，不能删除'
                ]);
            }
            //删除退库单
            $updateResult = Db::table('AssetReturnsBill')
                ->where('AssetReturnsBill_id', $AssetReturnsBill_id)
                ->delete();
            $deleteResult = Db::table('AssetReturnsBill_assets')
                ->where('AssetReturnsBill_id', $AssetReturnsBill_id)
                ->delete();
            //直接返回json结果
            if (!$updateResult || !$deleteResult) {
                Db::rollback();
                throw new \Exception('删除退库单失败');
            }else{
                Db::commit();
                //返回删除成功信息
                return json(['code' => 200,'msg' => '删除成功']);
            }

        }
        catch (\Exception$e) {
            Db::rollback();
            return json([
                'code' => 500,
                'msg' => $e->getMessage()
            ]);
        }
        
        
        
        
    }

    //反审核退库单
    public function  uncheck_AssetReturnsBill()
    {

        $userRoot = $this->request->auth['data']->user->user_root;
        $userId = $this->request->auth['data']->user->user_id;


        // 根据用户ID获取公司ID
        $companyId = Db::name('user')->where('user_id', $userId)->value('user_company_id');

        try {
            Db::startTrans();
            $AssetReturnsBill_id =Request::param('AssetReturnsBill_id');
            //验证退库单是否合法,是否未审核状态
            $result=Db::table('AssetReturnsBill')
                ->where('AssetReturnsBill_id',$AssetReturnsBill_id)
                ->where('AssetReturnsBill_state','已审核')
                ->find();
            //返回Json数据
            if(empty($result)){
                return json([
                    'code' => 201,
                    'msg' => '该退库单状态不是已审核状态，不能反审核'
                ]);
            }
            //先检查领用单状态
            $AssetReturnsBill_one = Db::table('AssetReturnsBill')
                ->where('AssetReturnsBill_id', $AssetReturnsBill_id)
                ->find();


            //判断是否能反审核
            $resultJson=uncheck_checkAssetBill($AssetReturnsBill_id,'AssetReturnsBill','退库');
            if($resultJson){
                return $resultJson;
            }



            if($AssetReturnsBill_one['AssetReturnsBill_state']=='已审核'){
            //反审核领用单
            $updateResult = Db::table('AssetReturnsBill')
                ->where('AssetReturnsBill_id', $AssetReturnsBill_id)
                ->update(['AssetReturnsBill_state' => '未审核']);
            //修改回该领用单对应的资产的所有资产信息，根据AssetReturnsBill_assets表中before_department_id和before_location_id字段修改
            $AssetReturnsBill_assets_one = Db::table('AssetReturnsBill_assets')
                ->where('AssetReturnsBill_id', $AssetReturnsBill_id)
                ->select()->toArray();
            for ($i = 0; $i < count($AssetReturnsBill_assets_one); $i++) {
                $Asset_id = $AssetReturnsBill_assets_one[$i]['assets_id'];
                $Asset_before_department_id = $AssetReturnsBill_assets_one[$i]['before_department_id'];
                $Asset_before_location_id = $AssetReturnsBill_assets_one[$i]['before_location_id'];
                $Asset_before_branch_id=$AssetReturnsBill_assets_one[$i]['before_branch_id'];
                $Asset_before_customer_id=$AssetReturnsBill_assets_one[$i]['before_customer_id'];
                $Asset_before_status=$AssetReturnsBill_assets_one[$i]['before_status'];


                $updateResult = Db::table('assets')
                    ->where('assets_id', $Asset_id)
                    ->update(['assets_department_id' => $Asset_before_department_id, 'assets_location_id' => $Asset_before_location_id,'assets_customer_id'=>$Asset_before_customer_id,'assets_status'=>$Asset_before_status,'assets_branch_id'=>$Asset_before_branch_id]);
                //删除对应的历史记录
                $deleteResult = Db::table('AssetHistories')
                    ->where('AssetHistories_bill_id', $AssetReturnsBill_id)
                    ->where('AssetHistories_assets_id', $Asset_id)
                    ->where('AssetHistories_type','退库')
                    ->delete();
                if (!$updateResult || !$deleteResult) {
                    Db::rollback();
                    throw new \Exception('反审核失败');
                }
            }

            //直接返回json结果
            if (!$updateResult) {
                Db::rollback();
            }
            Db::commit();
            return json(['code' => 200,'msg' => '反审核成功']);
            }
            
        } catch (\Exception $e) {
            Db::rollback();
            return json([
                'code' => 500,
                'msg' => $e->getMessage()
            ]);
        }
        
        
        


    }

}